package org.victoria.common.utils;

import org.hibernate.Query;
import org.hibernate.Session;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 辅助拼接HQL语句的工具类
 * Created by Administrator on 14-9-3.
 */
public class QueryHelper {

    //Form子句
    private String __handle_clause__;
    //Update子句
    private String __set_clause__;
    //Where子句
    private String __where_clause__;
    //OrderBy子句
    private String __order_by_clause__;
    //GroupBy子句
    private String __group_by_clause__;
    //query
    private String _query_;
    //count query
    private String __count__;
    //参数列表
    private List<Object> params;
    //className
    private String name;
    //alias
    private String alias;
    //select
    private String __select_clause__;
    //
    private Class clazz;

    public enum HelperEnum{
        UPDATE, SELECT
    }

    public QueryHelper(){
        __set_clause__ = "";
        __where_clause__ = "";
        __order_by_clause__ = "";
        _query_ = "";
        __select_clause__ = "";
        __group_by_clause__ = "";
        params = new ArrayList<Object>();
    }

    public QueryHelper(Class clazz){
        this();
        this.clazz = clazz;
    }


    public QueryHelper(Class clazz, HelperEnum t){
        this();
        this.clazz = clazz;
        name = clazz.getSimpleName();
        alias = clazz.getSimpleName();
        switch (t){
            case SELECT:
                __handle_clause__ = " FROM " + name + " as " + alias;
                break;
            case UPDATE:
                __handle_clause__ = " UPDATE " + name;
                break;
        }
    }

    /**
     * 拼接where子句
     * @param field 查询的字段名
     * @param param 参数
     * @return
     */
    public QueryHelper where(String field, Object param){
        if (isEmpty(__where_clause__)){
            __where_clause__ = " WHERE " + field + " =? ";
        }else {
            __where_clause__ += " AND " + field + " =? ";
        }
        if (param != null){
            params.add(param);
        }
        return this;
    }

    /**
     * 条件拼接where子句
     * @param position 如何为true则插入where语句，反之不插入
     * @param field 查询的字段名
     * @param param 参数
     * @return
     */
    public QueryHelper where(boolean position, String field, Object param){
       if (position)
           return where(field, param);
        return this;
    }


    public QueryHelper between(String field, Object param1, Object param2){
        __where_clause__ = isEmpty(__where_clause__)
                ? " WHERE " + field + " BETWEEN ? AND ? "
                : __where_clause__ + " AND " + field + "BETWEEN ? AND ? ";
        if (param1 != null){
            params.add(param1);
        }
        if (param2 != null){
            params.add(param2);
        }
        return this;
    }

    /**
     * 拼接特殊条件的where子句
     * @param condition 查询语句
     * @return
     */
    public QueryHelper where(String condition){
        if (isEmpty(__where_clause__)){
            __where_clause__ = " WHERE " + condition;
        }else{
            __where_clause__ += " AND " + condition;
        }
        return this;
    }

    /**
     *
     * @param field
     * @param param
     * @return
     */
    public QueryHelper like(String field, Object param){
        __where_clause__ = isEmpty(__where_clause__)
                ? " WHERE " + field + " like ? "
                : __where_clause__ + " AND " + field + " like ? ";
        if (param != null){
            params.add(param);
        }
        return this;
    }

    public QueryHelper like(boolean position, String field, Object param){
        if (position)
            return like(field, param);
        return this;
    }

    /**
     * 拼接order by子句
     * @param field 查询的字段名
     * @param asc true为升序，false为降序
     * @return
     */
    public QueryHelper orderBy(String field, boolean asc){
        if (isEmpty(__order_by_clause__)){
            __order_by_clause__ = " ORDER BY " + field + (asc? " ASC " : " DESC ");
        }else {
            __order_by_clause__ += " , " + field + (asc? " ASC " : " DESC ");
        }
        return this;
    }

    /**
     * 条件拼接order by子句
     * @param position 判断条件，true则插入order by语句，反之不插入
     * @param field 查询的字段名
     * @param asc true为升序，false为降序
     * @return
     */
    public QueryHelper orderBy(Boolean position, String field, boolean asc){
        if (position)
            return orderBy(field, asc);
        return this;
    }

    /**
     * 拼接set子句
     * @param field 查询的字段名
     * @param param 参数
     * @return
     */
    public QueryHelper set(String field, Object param){
        if (isEmpty(__set_clause__)){
            __set_clause__ = " SET " + field + " =? ";
        }else{
            __set_clause__ += ", " + field + " =? ";
        }
        if (param!=null)
            params.add(param);
        return this;
    }

    /**
     * 拼接set子句
     * @param condition set语句
     * @return
     */
    public QueryHelper set(String condition){
        if (condition == null || condition.trim().equals(""))
            return this;
        if (isEmpty(__set_clause__)){
            __set_clause__ = " SET " + condition;
        }else {
            __set_clause__ += ", " + condition;
        }
        return this;
    }

    /**
     * 条件拼接set子句
     * @param position 判断条件，true则插入set语句，反之不插入
     * @param field 查询的字段名
     * @param param 参数
     * @return
     */
    public QueryHelper set(boolean position, String field, Object param){
        if (position)
            return set(field, param);
        return this;
    }

    /**
     * 拼接IN语句
     * @param field
     * @param objects
     * @return
     */
    public QueryHelper in(String field, Collection objects){
        if (isEmpty(__where_clause__)){
            __where_clause__ += " WHERE " + field + " IN( ";
        }else {
            __where_clause__ += " AND " + field + " IN( ";
        }
        for (int i=0; i<objects.size()-1; i++){
            __where_clause__ += " ?, ";
        }
        __where_clause__ += " ?) ";
        if (objects.size()>0)
            params.addAll(objects);
        return this;
    }

    /**
     *
     * @param property
     * @return
     */
    public QueryHelper groupBy(String property){
        __group_by_clause__ = isEmpty(__group_by_clause__)
                ? " GROUP BY " + property
                : __group_by_clause__ + " , " + property;
        return this;
    }

    /**
     *
     * @param session
     * @return
     */
    public Query getCountSQLQuery(Session session) {
        return isEmpty(__count__)
                ? session.createQuery(this.getQueryCountHql())
                : session.createSQLQuery(this.getQueryCountHql());
    }

    /**
     * append SQL语句
     * @param queryStr query语句
     * @return
     */
    public QueryHelper append(String queryStr){
        this._query_ += " ";
        this._query_ += queryStr;
        return this;
    }

    public QueryHelper select(String... selects){
        StringBuilder builder = new StringBuilder();
        builder.append("SELECT ");
        for (String item : selects){
            builder.append(" $."+item);
            builder.append(",");
//            builder.append(item);
        }
        String str = builder.toString();
        __select_clause__ =  str.substring(0, str.lastIndexOf(","));
        return this;
    }

    /**
     * 获得查询总记录的HQL语句（没有order by）
     * @return
     */
    public String getQueryCountHql(){
        String countSQL =  !isEmpty(__count__)
                ? __count__
                : (" SELECT COUNT(*) " + __handle_clause__ + __where_clause__);
        return countSQL.replace("$.", alias+".");
    }

    /**
     * 获得查询的HQL语句
     * @return
     */
    public String getQueryHql(){
            return isEmpty(_query_)
                    ? (__select_clause__ + __handle_clause__ + __set_clause__ + __where_clause__ + __group_by_clause__ + __order_by_clause__).replace("$.", alias+".")
                    : get_query_();
    }

    /**
     * 对queryStr做一些处理，1、在?之间插入逗号
     * @return
     */
    private String get_query_() {
        Pattern pattern = Pattern.compile("\\?[ ]*\\?");
        for (Matcher m = pattern.matcher(_query_); m.find(); m = pattern.matcher(_query_)){
            _query_ = m.replaceAll("?,?");
        }
        return _query_;
    }

    /**
     * 获得正确的Query
     */
    public Query getQuery(Session session){
        return this.isOriginal()
                ? session.createSQLQuery(this.getQueryHql()).addEntity(clazz)
                : session.createQuery(this.getQueryHql());
    }

    public void setCountSql(String sql){
        __count__ = sql;
    }

    /**
     * 判断是使用Hql还是原生的sql
     * @return
     */
    public boolean isOriginal(){
        return !isEmpty(_query_);
    }

    /**
     * 获得参数列表
     * @return
     */
    public List<Object> getParams() {
        return params;
    }

    /**
     *
     * @param o
     */
    public void putParam(Object o){
        params.add(o);
    }

    /**
     * 
     * @param str
     * @return
     */
    private boolean isEmpty(String str){
        return  str == null || str.equals("");
    }

    public String get__where_clause__() {
        return __where_clause__;
    }

    public String get__group_by_clause__() {
        return __group_by_clause__;
    }
}
